package FileReader;
import java.io.*;

/**
 * Created by Wang BinLu on 2016/10/28.
 * EXTRA KNOWLEDGE!!
 * 1. to know the BIT AND 0xff, you can refer to this website: http://blog.csdn.net/z69183787/article/details/36183839
 * 2. we use <<24>>16 instead of simply <<8 because we need to keep the sign bit on the top bit of int according to the sign bit of the byte
 * 3. use csv with \n may improve the reading speed of matlab because file are usually read by lines, if using txt, there will be only one line.
 */
public class SourceReader
{

    public static void MusicToByteArray (File musicFile, byte[] buffer) throws Exception
    {
        FileInputStream fi = new FileInputStream(musicFile);
        int offset = 0;
        int numRead = 0;
        while (offset < buffer.length && (numRead = fi.read(buffer, offset, buffer.length - offset)) >= 0)
        {
            offset += numRead;
        }
        // Make sure that all the data in the music is read
        if (offset != buffer.length)
        {
            throw new IOException("Could not completely read file "
                    + musicFile.getName());
        }
    }

    /**
     * This function is used to inspect the format of the music and output the double array
     * according to the input byte array, if the format is wrong, it just print "error" on the
     * console instead of throw a exception.
     * Each part of the head information inspection has been divided.
     *
     * @param musicBytesArray    the input byte array of music
     */
    public static double[] MusicFormatInspectionAndDataCollection(byte[] musicBytesArray)
    {
        byte[] ChunkIDByte = new byte[4];
        System.arraycopy(musicBytesArray, 0, ChunkIDByte, 0, 4);
        String ChunkID = new String(ChunkIDByte);

        int AudioFormatInt = ((musicBytesArray[21]&0xff)<<24>>16)|musicBytesArray[20];

        int NumChannelsInt = ((musicBytesArray[23]&0xff)<<24>>16)|musicBytesArray[22];

        int SampleRateInt = ((musicBytesArray[27]&0xff)<<24)|((musicBytesArray[26]&0xff)<<16)|((musicBytesArray[25]&0xff)<<8)|musicBytesArray[24];

        int BitsPerSampleInt = ((musicBytesArray[35]&0xff)<<8)|musicBytesArray[34];

        if((!ChunkID.equals("RIFF"))||(AudioFormatInt!=1)||(NumChannelsInt!=1)||(SampleRateInt!=44100)||(BitsPerSampleInt!=16))
            System.out.println("Format Error!");

        double[] musicDataInt = new double[(musicBytesArray.length-46)/2];
        for(int i=46,j=0;i<musicBytesArray.length;i+=2)
        {
            musicDataInt[j++]=(musicBytesArray[i+1]<<24>>16)|(musicBytesArray[i]&0xff);
        }
        return musicDataInt;
    }
}
